package com.atguigu.gmall.activity.controller;

import com.atguigu.gmall.activity.service.SeckillGoodsService;
import com.atguigu.gmall.activity.util.CacheHelper;
import com.atguigu.gmall.common.constant.MqConst;
import com.atguigu.gmall.common.constant.RedisConst;
import com.atguigu.gmall.common.result.Result;
import com.atguigu.gmall.common.result.ResultCodeEnum;
import com.atguigu.gmall.common.service.RabbitService;
import com.atguigu.gmall.common.util.AuthContextHolder;
import com.atguigu.gmall.common.util.DateUtil;
import com.atguigu.gmall.common.util.MD5;
import com.atguigu.gmall.model.activity.OrderRecode;
import com.atguigu.gmall.model.activity.SeckillGoods;
import com.atguigu.gmall.model.activity.UserRecode;
import com.atguigu.gmall.model.order.OrderDetail;
import com.atguigu.gmall.model.order.OrderInfo;
import com.atguigu.gmall.model.user.UserAddress;
import com.atguigu.gmall.order.client.OrderFeignClient;
import com.atguigu.gmall.product.client.ProductFeignClient;
import com.atguigu.gmall.user.client.UserFeignClient;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.*;

/**
 * @Author LEO
 * @Date 2021年12月26日 0:10
 */
@RestController
@RequestMapping("/api/activity/seckill")
public class SeckillGoodsApiController {
    @Autowired
    private SeckillGoodsService seckillGoodsService;

    @Autowired
    private UserFeignClient userFeignClient;

    @Autowired
    private ProductFeignClient productFeignClient;

    @Autowired
    private RabbitService rabbitService;

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private OrderFeignClient orderFeignClient;
    /**
     * 返回全部列表
     *
     * @return
     */
    @GetMapping("/findAll")
    public Result findAll() {
        return Result.ok(seckillGoodsService.findAll());
    }

    /**
     * 获取实体
     *
     * @param skuId
     * @return
     */
    @GetMapping("/getSeckillGoods/{skuId}")
    public Result getSeckillGoods(@PathVariable("skuId") Long skuId) {
        return Result.ok(seckillGoodsService.getSeckillGoods(skuId));
    }

    //获取下单码： 为什么要下单码  防止用户非法抢购
    @GetMapping("auth/getSeckillSkuIdStr/{skuId}")
    public Result getSeckillSkuIdStr(@PathVariable("skuId") Long skuId, HttpServletRequest request) {
        // 根据当前skuId 查询到秒杀商品是谁
        SeckillGoods seckillGoods = seckillGoodsService.getSeckillGoods(skuId);
        String userId = AuthContextHolder.getUserId(request);

        if (!StringUtils.isEmpty(userId)) {
            Date curTime = new Date();
            // 比较时间  seckillGoods.getStartTime() <= curTime true    curTime<=seckillGoods.getEndTime()
            if (DateUtil.dateCompare(seckillGoods.getStartTime(), curTime) && DateUtil.dateCompare(curTime, seckillGoods.getEndTime())) {
                // 在秒杀时间范围内
                //可以动态生成，放在redis缓存
                String skuIdStr = MD5.encrypt(userId);
                return Result.ok(skuIdStr);
            }
        }
        return Result.fail().message("获取下单码失败");
    }

    /**
     * 根据用户和商品ID实现秒杀下单
     * @param skuId
     * @return
     */
    @PostMapping("auth/seckillOrder/{skuId}")
    public Result seckillOrder(@PathVariable("skuId") Long skuId, HttpServletRequest request) throws Exception {
        // 校验下单码，只有正确获得下单码的请求才是合法请求
        String skuIdStr=request.getParameter("skuIdStr");
        //获取用户Id 然后再加密，与skuIdStr 做个比较
        String userId = AuthContextHolder.getUserId(request);
        if (!skuIdStr.equals(MD5.encrypt(userId))){
            // 下单码不正确
            return Result.build(null, ResultCodeEnum.SECKILL_ILLEGAL);
        }
        //校验状态码state  redis 订阅发布
        String state= (String) CacheHelper.get(skuId.toString());
       if (StringUtils.isEmpty(state)){
           return Result.build(null, ResultCodeEnum.SECKILL_ILLEGAL);
       }else if ("0".equals(state)){
           return Result.build(null, ResultCodeEnum.SECKILL_FINISH);
       }else {
           // 商品可以秒杀
           UserRecode userRecode = new UserRecode();
           userRecode.setUserId(userId);
           userRecode.setSkuId(skuId);
           //发送到mq
           rabbitService.sendMessage(MqConst.EXCHANGE_DIRECT_SECKILL_USER,MqConst.ROUTING_SECKILL_USER,userRecode);
           return Result.ok();
       }

    }


    // 检查秒杀状态
    @GetMapping(value = "auth/checkOrder/{skuId}")
    public Result checkOrder(@PathVariable("skuId") Long skuId, HttpServletRequest request) {
        //当前登录用户
        String userId = AuthContextHolder.getUserId(request);
        return seckillGoodsService.checkOrder(skuId, userId);
    }


    /**
     * 秒杀确认订单
     * @param request
     * @return
     */
    @GetMapping("auth/trade")
    public Result trade(HttpServletRequest request) {

        String userId = AuthContextHolder.getUserId(request);
        List<UserAddress> userAddressList = userFeignClient.findUserAddressListByUserId(Long.parseLong(userId));

        // 送货清单  hset       orderKey=seckill:orders   field=userId  value=orderRecode
        String orderKey= RedisConst.SECKILL_ORDERS;
       OrderRecode orderRecode= (OrderRecode) redisTemplate.boundHashOps(orderKey).get(userId);
       if (orderRecode == null){
           return Result.fail().message("下单失败");
       }
       // 获取到当前的秒杀商品
        SeckillGoods seckillGoods = orderRecode.getSeckillGoods();

       List<OrderDetail> orderDetailList=new ArrayList<>();
        OrderDetail orderDetail = new OrderDetail();
        orderDetail.setSkuId(seckillGoods.getSkuId());
        orderDetail.setSkuName(seckillGoods.getSkuName());
        orderDetail.setImgUrl(seckillGoods.getSkuDefaultImg());
        orderDetail.setSkuNum(orderRecode.getNum());
        orderDetail.setOrderPrice(seckillGoods.getCostPrice());
        // 添加到集合
        orderDetailList.add(orderDetail);
        // 计算总金额
//        OrderInfo orderInfo = new OrderInfo();
//        orderInfo.setOrderDetailList(orderDetailList);
//        orderInfo.sumTotalAmount();
//         map.put("totalAmount", orderInfo.getTotalAmount())
        Map<String, Object> map = new HashMap<>();
        map.put("userAddressList", userAddressList);
        map.put("detailArrayList", orderDetailList);
        map.put("totalNum","1");
        // 保存总金额
        map.put("totalAmount", seckillGoods.getCostPrice());
        return Result.ok(map);
    }

    // 提交订单
    @PostMapping("auth/submitOrder")
    public Result submitOrder(@RequestBody OrderInfo orderInfo, HttpServletRequest request) {
        String userId = AuthContextHolder.getUserId(request);
        orderInfo.setUserId(Long.parseLong(userId));
        Long orderId = orderFeignClient.submitOrder(orderInfo);
        if (null == orderId) {
            return Result.fail().message("提交订单失败！");
        }
        //删除缓存的信息(预下单信息) setnx RedisConst.SECKILL_ORDERS ;  userId
        redisTemplate.boundHashOps(RedisConst.SECKILL_ORDERS).delete(userId);
        //存储一个真正下单的数据到缓存
        redisTemplate.boundHashOps(RedisConst.SECKILL_ORDERS_USERS).put(userId, orderId.toString());
        return Result.ok(orderId);
    }
}
